<?php
/**
 *Source de la classe {@link http://www.devshed.com/c/a/PHP/Userdefined-Interfaces-in-PHP-5-Turning-MySQL-Classes-into-Interface-Implementers/2/}
 *
 * @author KAMGANG Ghislain <kamgangf@yahoo.fr>
 * @version   1.0
 * @package MYSQL
 */
/**
 *
 * @abstract Classe d'acc�s � la base mysql (DAO)
 * @package MYSQL
 *         
 */
class MySQL {
	static $instance;
	/**
	 * #@+
	 *
	 * @access private
	 * @var bool
	 */
	private $statusHost; // statut de connexion au serveur
	private $status; // statut de connexion � la base
	/**
	 * #@-
	 */
	/**
	 * #@+
	 *
	 * @access private
	 * @var ressource
	 */
	public $conId; // connection identifier
	/**
	 * #@-
	 */
	/**
	 * #@+
	 *
	 * @access private
	 * @var string
	 */
	private $host; // MySQL host
	private $user; // MySQL username
	private $password; // MySQL password
	private $database; // MySQL database
	/**
	 * #@-
	 */
	/**
	 *
	 * @access private
	 * @var array Tableau de toutes les requ�tes r�alis�es par l'instance courante de l'objet MYSQL
	 */
	private $queryList = array ();
	/**
	 * Fonction constructrice de la classe , se connecte au serveur et � la base (si pr�cis�)
	 * Uses Singleton Pattern
	 *
	 * @access private
	 * @param array $options
	 *        	tableau cl� -valeur de param�tres de connexion � la base mysql : host-user-password-database
	 * @return object
	 */
	private function __construct($options = array()) {
		// validate incoming parameters
		if (count ( $options ) < 3) {
			throw new Exception ( 'Invalid number of connection parameters' );
		}
		foreach ( $options as $parameter => $value ) {
			$this->{$parameter} = $value;
		}
		// connect to MySQL
		if (($this->database == '') && (! $this->statusHost))
			$this->connectHost ();
		if (($this->database != '') && (! $this->status))
			$this->connectDB ();
	}
	static function getInstance($options = array()) {
		if (empty ( self::$instance )) {
			if (empty ( $options )) {
				throw new Exception ( 'Param�tres de connexion non renseign�s' );
			}
			self::$instance = new MYSQL ( $options );
		}
		return self::$instance;
	}
	/**
	 * Se connecte au serveur uniquement
	 *
	 * @access public
	 * @return mixed met � jour statusHost
	 */
	public function connectHost() {
		if (! $this->conId = mysql_connect ( $this->host, $this->user, $this->password, $this->database )) {
			// ~ if(!$this->conId=mysqli_connect($this->host,$this->user,$this->password,$this->database)){
			throw new Exception ( 'Error connecting to the server' );
		}
		$this->statusHost = true;
	}
	
	/**
	 * Se connecte au serveur et � la base
	 *
	 * @access public
	 * @return mixed met � jour status
	 */
	public function connectDB() {
		if (! $this->statusHost)
			$this->connectHost ();
			// ~ if(!mysql_select_db($this->database,$this->conId)){
			// ~ throw new Exception('Error selecting database :'.$this->database);
			// ~ // throw new Exception('Error selecting database :'.$this->database.' for user:'.$this->user.' with password:'.$this->password);
			// ~ }
		$this->status = true;
	}
	/**
	 * Initialise la base de donn�e de connection
	 *
	 * @param $db nom
	 *        	de la base sql � connecter
	 * @access public
	 */
	public function setDB($db) {
		$this->database = $db;
	}
	/**
	 * Affiche un message d'erreur MYSQL
	 *
	 * @param $sql requ�te
	 *        	SQL �chou�e
	 * @access private
	 */
	private function errmysql($sql) {
		echo "<br> $sql <br>";
		echo mysql_errno () . ": " . mysql_error () . "\n";
	}
	/**
	 * Ex�cute une requ�te sql sur la base et met � jour la variable status
	 *
	 * @param $query requ�te
	 *        	SQL
	 * @param $error message
	 *        	d'erreur si �chec
	 * @access private
	 * @return object objet Result
	 * @see Result
	 */
	public function query($query, $error = '') {
		array_push ( $this->queryList, $query );
		if (! $this->result = mysql_query ( $query, $this->conId )) 
		// ~ if(!$this->result= mysqli_query($query,$this->conId))
		{
			$this->errmysql ( $query );
			throw new Exception ( $error . '-- Error performing query: ' . $query );
		}
		// return new Result object
		return new Result ( $this, $this->result );
	}
	public function getDatabase() {
		return $this->database;
	}
	public function getQueryList() {
		return $this->queryList;
	}
	public function printQueryList() {
		echo "<pre style=\"text-align:left\">";
		print_r ( $this->getQueryList () );
		echo "</pre>";
	}
}

/**
 * Here is the class Result
 *
 * @abstract Objet pour ex�cution des requ�tes SQL
 * @see MySQL
 * @package MYSQL
 *         
 */
class Result {
	private $output; // dynamic output
	private $mysql; // instance of MySQL object
	public $result; // MySQL result set
	/**
	 *
	 * @abstract Fonction constructrice de la classe
	 * @access public
	 * @param ressource $result
	 *        	ressource mysql
	 * @param object $mysql
	 *        	objet mysql
	 */
	public function __construct($mysql, $result) {
		$this->mysql = $mysql;
		$this->result = $result;
	}
	/**
	 * Cr�e un tableau associatif de l'enregistrement
	 *
	 * @access public
	 * @return array tableau associatif du r�sultat
	 */
	public function fetchRow() {
		return mysql_fetch_assoc ( $this->result );
		// ~ return mysqli_fetch_assoc($this->result);
	}
	/**
	 *
	 * @access public
	 * @return int nombre de lignes
	 */
	public function countRows() {
		$rows = mysql_num_rows ( $this->result );
		if (($rows !== 0) && (! $rows)) {
			throw new Exception ( 'Error counting rows' );
		}
		return $rows;
	}
	/**
	 *
	 * @access public
	 * @return int nombre de lignes affect�es par la derni�re requete mysql
	 */
	public function countAffectedRows() {
		if (! $rows = mysql_affected_rows ( $this->mysql->conId )) {
			throw new Exception ( 'Error counting affected rows' );
		}
		return $rows;
	}
	/**
	 *
	 * @access public
	 * @return int id g�n�r�e par la derni�re requete INSERT
	 */
	public function getInsertID() {
		if (! $id = mysql_insert_id ( $this->mysql->conId )) {
			throw new Exception ( 'Error getting ID' );
		}
		return $id;
	}
	/**
	 *
	 * @access public
	 * @return string donn�es associ�s � un enregistrement pr�cis
	 */
	public function getResult($row, $field = '') {
		if (! $string = mysql_result ( $this->result, $row, $field )) {
			throw new Exception ( 'Error getting string' );
		}
		return $string;
	}
	/**
	 * D�place le pointeur interne de la ressource
	 *
	 * @access public
	 */
	public function seekRow($row = 0) {
		if (! mysql_data_seek ( $this->result, $row )) {
			throw new Exception ( 'Error seeking data' );
		}
	}
	/**
	 * Construit un Tableau en HTML des donn�es
	 *
	 * @access public
	 */
	public function toHTML() {
		$this->output = '<table>';
		while ( $row = $this->fetchRow () ) {
			$this->output .= '<tr>';
			foreach ( $row as $field => $value ) {
				$this->output .= '<td>' . $value . '</td>';
			}
			$this->output .= '</tr>';
		}
		$this->output .= '</table>';
		return $this->output;
	}
	public function countFields() {
		$rows = mysql_num_fields ( $this->result );
		if (($rows !== 0) && (! $rows)) {
			throw new Exception ( 'Error counting rows' );
		}
		return $rows;
	}
	public function fieldsName($i) {
		$rows = mysql_field_name ( $this->result, $i );
		if (($rows !== 0) && (! $rows)) {
			throw new Exception ( 'Error counting rows' );
		}
		return $rows;
	}
}
?>
